<template>
    <div>
        <!-- 权限菜单内容 -->
        <div v-if="isShow">
            <el-input disabled v-model="role.roleName"></el-input>
            <el-tree style="margin: 20px 0px;" :data="permissionData" node-key="id"
                :default-expanded-keys="permissionIdList" :default-checked-keys="permissionIdList" empty-text="暂无数据"
                show-checkbox :props="defaultProps" @check="handleChecked">
            </el-tree>
            <el-button type="primary" @click="savePermission">保存</el-button>
            <el-button @click="isShow = false">取消</el-button>

        </div>
        <!-- 角色管理内容 -->
        <div v-else>
            <el-input style="width: 200px; margin-right: 10px;" placeholder="请输入角色名称"
                v-model="searchObj.roleName"></el-input>
            <el-button type="primary" icon="el-icon-search" @click="search">查询</el-button>
            <el-button @click="clear">清空</el-button>

            <div class="role-list">
                <el-button type="primary" icon="el-icon-plus" @click="addRole">添加</el-button>
                <el-button type="danger" icon="el-icon-delete" @click="deleteChecked"
                    :disabled="roleIdList.length<1">批量删除</el-button>
                <!-- 用户列表 -->
                <el-table :data="roleList" border stripe style="margin-top: 20px;" empty-text="暂无数据"
                    v-loading="roleLoading" @selection-change="handleSelectionChange">
                    <el-table-column type="selection" width="60" align="center"></el-table-column>
                    <el-table-column label="序号" type="index" width="80" align="center"></el-table-column>
                    <el-table-column label="角色名称" prop="roleName" width="width" align="center"></el-table-column>
                    <el-table-column label="操作" prop="prop" width="300" align="center">
                        <template slot-scope="{row,$index}">
                            <el-button type="info" icon="el-icon-info" @click="goPermission(row)"></el-button>
                            <el-button type="primary" icon="el-icon-edit" @click="updateRole(row)"></el-button>
                            <el-popconfirm :title="`确定删除${row.roleName}吗？`" @onConfirm="deleteRole(row)">
                                <el-button style="margin-left: 10px;" type="danger" slot="reference"
                                    icon="el-icon-delete"></el-button>
                            </el-popconfirm>
                        </template>
                    </el-table-column>
                </el-table>
                <!-- 分页器 -->
                <!-- 
            current-page: 当前是第几页
            total: 一共有多少条数据需要展示
            page-size: 每一页需要展示多少条数据
            page-sizes: 设置每一页展示多少条数据
            pager-count: 连续的页码数
            layout: 设置分页器的布局| -> : 代表将箭头后的元素移动至页面最右端
            @current-change="handleCurrentChange" : 切换页码时触发
            @size-change="handleSizeChange" : 当前页面显示数据条数改变时触发
            @prev-click="handlePrevClick" : 点击上一页
            @next-click="handleNextClick" : 点击下一页
            -->
                <el-pagination background style="margin-top: 30px; text-align: left;" :current-page="page"
                    :total="total" :page-size="limit" :page-sizes="[3,5,7]" :pager-count="7"
                    layout="prev,pager,next,jumper,->,sizes,total" @current-change="handleCurrentChange"
                    @size-change="handleSizeChange" @prev-click="handlePrevClick" @next-click="handleNextClick">
                </el-pagination>
            </div>

            <!-- 添加 | 修改用户弹框 -->
            <el-dialog :title="isAdd?'添加角色':'修改角色'" :visible.sync="addOrUpdataDialogVisible" width="30%" top="30vh">
                <span>
                    <el-form :model="role" ref="formRules" :rules="rules" label-width="80px" label-position="top">
                        <el-form-item :label="isAdd?'请输入新角色名称':'请修改角色名称'" prop="roleName">
                            <el-input placeholder="请输入角色名称" v-model="role.roleName"></el-input>
                        </el-form-item>
                    </el-form>
                </span>
                <span slot="footer" class="dialog-footer">
                    <el-button @click="addOrUpdataDialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="confirmAddOrAditRole">确定</el-button>
                </span>
            </el-dialog>
        </div>

    </div>
</template>
<script>
    export default {
        name: "Role",
        mounted() {
            this.getRoleList() // 组件挂载时获取分页列表
        },
        data() {
            return {
                isShow: false,// 是否展示权限菜单
                roleLoading: false, // table的加载动画
                searchObj: { // 携带给服务器的搜索角色名称 | 携带给服务器的query参数必须要用对象储存
                    roleName: '', // 角色名称
                },
                total: 0, // 总共多少条数据
                page: 1, // 当前页码
                limit: 3, // 每页显示多少条数据
                roleList: [], // 角色列表
                roleIdList: [], // 角色id列表
                addOrUpdataDialogVisible: false, // 显示添加弹框
                isAdd: true, // true ：添加弹框 | false ：修改弹框
                role: { // 携带给服务器的角色数据
                    roleName: '' // 角色名称
                },
                rules: { // 添加|修改用户的表单验证规则
                    roleName: [
                        { required: true, message: '请输入角色名称', trigger: 'change' },
                    ],
                },
                permissionData: [], //权限菜单数据
                defaultProps: {
                    children: 'children',
                    label: 'name'
                },
                permissionIdList: [], //收集菜单id列表
            }
        },
        methods: {
            // 切换页码时触发
            handleCurrentChange(page) {
                this.page = page
                this.getRoleList()
            },
            // 当前页面显示数据条数改变时触发
            handleSizeChange(limit) {
                this.limit = limit
                this.getRoleList()
            },
            // 点击上一页
            handlePrevClick(page) {
                this.page = page
                this.getRoleList()
            },
            // 点击下一页
            handleNextClick(page) {
                this.page = page
                this.getRoleList()
            },
            // 获取角色列表数据
            async getRoleList() {
                this.roleLoading = true // 显示表格加载动画
                const { page, limit, searchObj } = this
                const result = await this.$api.role.reqGetRoleList(page, limit, searchObj)
                if (result.code == 20000) {
                    this.roleLoading = false // 关闭表格加载动画
                    this.total = result.data.total
                    this.roleList = result.data.items
                }
            },
            // 搜索角色
            search() {
                if (this.searchObj.roleName) {
                    this.getRoleList()
                }
            },
            // 清空搜索内容
            clear() {
                this.searchObj.roleName = '' // 将用户名输入框清空
                this.getRoleList() // 重新获取用户列表
            },
            // 添加角色
            addRole() {
                this.role = {} // 清空数据
                this.addOrUpdataDialogVisible = true // 显示添加角色弹框
                this.isAdd = true // 当前为添加角色弹框
            },
            // 修改角色
            updateRole(row) {
                this.addOrUpdataDialogVisible = true // 显示添加角色弹框
                this.isAdd = false // 当前为添加角色弹框
                // 展示角色名称并收集角色id
                this.role = {
                    roleName: row.roleName,
                    id: row.id
                }
            },
            // 确认添加或修改角色
            async confirmAddOrAditRole() {
                // 通过ref获取当前表单，验证通过再进入逻辑判断
                this.$refs.formRules.validate(async (valid) => {
                    if (valid) {
                        if (this.isAdd) { // 当前为添加弹框
                            this.$message({
                                type: 'success',
                                message: '添加成功！'
                            })
                            this.addOrUpdataDialogVisible = false // 隐藏添加用户弹框

                            // 收集表单数据提交到服务器
                            const result = await this.$api.role.reqAddRole(this.role)
                            if (result.code == 20000) {
                                this.getRoleList() //重新获取分页数据
                            }
                        } else { // 当前为修改弹框
                            this.$message({
                                type: 'success',
                                message: '修改成功！'
                            })
                            this.addOrUpdataDialogVisible = false // 隐藏添加用户弹框

                            // 收集表单数据提交到服务器
                            const result = await this.$api.role.reqUpdataRole(this.role)
                            if (result.code == 20000) { // 修改成功
                                this.getRoleList() //重新获取分页数据
                            }
                        }

                    }
                })
            },
            // 删除角色
            async deleteRole(row) {
                const result = await this.$api.role.reqDeleteRole(row.id)
                if (result.code == 20000) {
                    this.getRoleList()
                }
            },
            // // 获取选中的用户id列表 | 通过@selection-change事件可以获取当前选中的对象列表
            handleSelectionChange(selection) {
                const idList = []
                selection.forEach(item => {// 遍历数组
                    idList.push(item.id) // 收集数组中每条元素的id并push到idList中
                });
                this.roleIdList = [...idList] // 通过浅拷贝收集选中元素的id
            },
            // 删除选中角色 
            async deleteChecked() {
                this.$confirm('此操作将永久删除选中的角色, 是否继续?', '批量删除', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(async () => {
                    this.$message({
                        type: 'success',
                        message: '删除成功!'
                    });
                    const result = await this.$api.role.reqDeleteRoleList(this.roleIdList)
                    if (result.code == 20000) { // 删除成功
                        this.getRoleList() // 重新获取角色分页列表
                    }
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });
            },
            // 收集选中权限的id
            computedChecked(data) {
                data.forEach(item => {
                    // select:true 则代表选择了该权限
                    if (item.select) {
                        this.permissionIdList.push(item.id)
                    }
                    if (item.children && item.children.length > 0) {
                        // 递归 | 多层级嵌套的数据需要通过递归调用函数
                        this.computedChecked(item.children)
                    }
                    return true
                })
            },

            // 进入权限菜单
            async goPermission(row) {
                this.isShow = true // 显示权限菜单
                this.role.roleName = row.roleName // 展示当前角色名称
                this.role.roleId = row.id // 收集当前角色id

                const result = await this.$api.role.reqGetPermission(row.id)
                if (result.code == 20000) {
                    this.permissionData = result.data.children // 存储全部的权限
                    // 展示已选择的权限
                    this.computedChecked(result.data.children)

                }
            },
            // 当前选中权限
            handleChecked(item, data) { // item:当前选中的节点信息，data:所有相关的信息（包括选中信息）
                this.permissionIdList = data.checkedKeys // 收集当前选中的权限id
            },
            // 保存权限
            async savePermission() {
                // 整理参数
                const data = {
                    permissionIdList: this.permissionIdList,
                    roleId: this.role.roleId
                }
                const result = await this.$api.role.reqDoAssignAcl(data)
                if (result.code == 20000) {
                    this.$message({
                        type: 'success',
                        message: '保存成功！'
                    })
                    this.isShow = false // 关闭权限菜单
                }
                //清空数据
                this.permissionData = []
                this.permissionIdList = []
            }
        },
    }
</script>
<style scoped>
    .role-list {
        margin-top: 30px;
    }
</style>